import numpy as np
import matplotlib.pyplot as plt
#超平面模型
def model(x,theta):
    return x.dot(theta)
#sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
#代价函数  交叉熵函数
def cost(h,y):
    return -1/len(y)*np.sum(y*np.log(h)+(1-y)*np.log(1-h))
#梯度下降
def grad(x,y,alpha=0.1,iter0=5000):
    m,n=x.shape
    theta=np.zeros(n)
    J=np.zeros(iter0)
    for i in range(iter0):
        #z：样本点到超平面的距离
        z=model(x,theta)
        #预测值
        h=sigmoid(z)
        J[i]=cost(h,y)
        #梯度
        dt=1/m*x.T.dot(h-y)
        theta-=alpha*dt
    return h,theta,J

if __name__ == '__main__':
    data=np.loadtxt('ex2data1.txt',delimiter=',')

    x=data[:,:-1]
    y=data[:,-1]

    miu=np.mean(x,axis=0)
    sigma=np.std(x,axis=0)
    x=(x-miu)/sigma

    X=np.c_[np.ones(len(x)),x]

    h,theta,J=grad(X,y)
    plt.plot(J)
    plt.show()

    plt.scatter(x[:,0],x[:,1],c=y)

    min_x1=np.min(x[:,0])
    max_x1=np.max(x[:,0])

    min_x2=-(theta[0]+theta[1]*min_x1)/theta[2]
    max_x2=-(theta[0]+theta[1]*max_x1)/theta[2]

    plt.plot([min_x1,max_x1],[min_x2,max_x2],c='r')
    plt.show()